<?php

namespace App\Containers\AppSection\Signature\Actions;

use App\Containers\AppSection\File\Tasks\DownloadFileTask;
use App\Containers\AppSection\File\Tasks\FindFileByIdTask;
use App\Containers\AppSection\File\Tasks\UpdateFileTask;
use App\Containers\AppSection\Log\Tasks\CreateLogTask;
use App\Containers\AppSection\Signature\Models\Signature;
use App\Containers\AppSection\Signature\Tasks\CreateSignatureTask;
use App\Ship\Cryptopro\CryptoHelper;
use App\Ship\Exceptions\BadRequestException;
use App\Ship\Exceptions\CreateResourceFailedException;
use App\Ship\Exceptions\NotFoundException;
use App\Ship\Parents\Actions\Action;
use App\Ship\Parents\Requests\Request;

class CreateSignatureAction extends Action
{
    private CryptoHelper $crypto;

    public function __construct()
    {
        $this->crypto = new CryptoHelper();
    }

    /**
     * @throws NotFoundException
     * @throws CreateResourceFailedException
     * @throws BadRequestException
     */
    public function run(Request $request): Signature
    {
        $sign = $request->getInputByKey('sign', '');
        $fileId = $request->getInputByKey('file_id', '');

        $file = app(FindFileByIdTask::class)->run($fileId);
        $fileData = app(DownloadFileTask::class)->run($file->id);

        $verify = $this->crypto->Verify($fileData, $sign);
        if ($verify === false) {
            throw new BadRequestException('Подпись не является действительной!');
        }

        $signature = app(CreateSignatureTask::class)->run($sign, $verify[0]->cert, $file->id, $request->profile()->id, $verify[0]->ts);

        app(UpdateFileTask::class)->run($file->id, ["signature_id" => $signature->id]);


        app(CreateLogTask::class)->run($request->profile()->id, "Файл №{$file->id} подписан", 'signature');

        return $signature;
    }
}
